package tehMod;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.swing.text.NavigationFilter;

import tehUtils.BlockFinder;
import tehUtils.BlockInstance;

import net.minecraft.src.*;
import net.minecraft.src.forge.ForgeHooks;

import net.minecraft.client.Minecraft;

public class EntityTehVillager extends EntityVillager {
	
    public InventoryTehVillager inventory;
    public Container inventorySlots;
    public int[] villageChestPos;
    protected boolean followingPlayer = false;
    
    public ItemStack itemInUse;
    public int itemInUseCount;
    public int nextAttack = 0;
    
    public int swingProgressInt = 0;
    public boolean isSwinging = false;
    
    public BlockInstance targetBlock;
    public Entity waypoint;
    public long blockWait = -1;
    
    public boolean taskGathering = true;
    public boolean taskReturning = false;
	
	public EntityTehVillager(World world) {
		super(world);
		texture = "/mob/char.png";
		
		inventory = new InventoryTehVillager(this);
		inventory.setInventorySlotContents(0, new ItemStack(Item.shovelSteel));
		
		moveSpeed = 0.5F;
		tasks.addTask(1, new EntityAISwimming(this));
		tasks.addTask(2, new VillagerAIGather(this));
		tasks.addTask(3, new VillagerAIDropoff(this));
	}
	
	@Override
	protected boolean isAIEnabled() {
		return true;
	}
	
	@Override
	public int getMaxHealth() {
		return 1;
	}
	
/*	public void onCollideWithItem(EntityItem entityitem) {
        if (worldObj.isRemote)
            return;
        if (!isEntityAlive())
        	return;
        
        ItemStack item = entityitem.item;

        worldObj.playSoundAtEntity(this, "random.pop", 0.2F, ((rand.nextFloat() - rand.nextFloat()) * 0.7F + 1.0F) * 2.0F);
        if (inventory.addItemStackToInventory(item))
            entityitem.setEntityDead();
        else {
        	returnToChest = true;
        	targetBlock = null;
        	waypoint = null;
        }
        
        System.out.println("My inventory contains:");
        for (int i=0; i < inventory.inventorySize; i++) {
        	ItemStack itemstack = inventory.getStackInSlot(i);
        	if (itemstack != null)
        		 System.out.printf("* %dx %s\n", itemstack.stackSize, itemstack.getItem().getItemName());
        }
	}*/
	
	@Override
	public void onDeath(DamageSource damagesource) {
		super.onDeath(damagesource);
		inventory.dropAllItems();
	}
	
	@Override
	public void onEntityUpdate() {
		super.onEntityUpdate();
		updateEntityActionState();
	}
	
	public double getDistanceToTarget() {
		if (waypoint != null)
			return getDistanceSq(waypoint.posX, waypoint.posY, waypoint.posZ);
		return -1;
	}
	
	public void followPlayer() {
		EntityPlayer player = worldObj.getClosestPlayerToEntity(this, -1d);
		if (getDistanceSqToEntity(player) > 16)
			setTarget(player);
		else
			setTarget(null);
	}
	
	public Entity findPlayerToAttack() {
		if (targetBlock != null) return waypoint;
		return null;
	}
	
	public void breakBlock(BlockInstance blockinst) {
		if (inventory.canHarvestBlock(blockinst.block)) {
			for (ItemStack drop : blockinst.getBlockDropped(0))
				inventory.addItemStackToInventory(drop);
		}
		blockinst.setBlock(0);
	}
	
	public void getClosestBlock() {
		try {
			AxisAlignedBB searchArea = AxisAlignedBB.getBoundingBox(posX + 6, posY - 2, posZ + 6,
																	posX - 6, posY + 2, posZ - 6);
			targetBlock = BlockFinder.getClosestBlock(searchArea, new int[] {Block.dirt.blockID, Block.grass.blockID});
			
			waypoint = new EntityWaypoint(worldObj, targetBlock.posX, targetBlock.posY, targetBlock.posZ);
			setTarget(waypoint);
		} catch (NullPointerException ex) {
			targetBlock = null;
		}
	}
	
	@Override
	public ItemStack getHeldItem() {
		return inventory.getCurrentItem();
	}
	
	public Item getEquippedItem() {
		return inventory.getCurrentItem().getItem();
	}
	
	public void setHeldItem(int slot) {
		if (slot >= inventory.getSizeInventory())
			throw new IndexOutOfBoundsException();
		inventory.currentSlot = slot;
	}
	
    public void setItemInUse(ItemStack itemstack, int i) {
        if (itemstack == itemInUse)
            return;

        itemInUse = itemstack;
        itemInUseCount = i;
    }
    
    public ItemStack getItemInUse() {
        return itemInUse;
    }

    public int getItemInUseCount() {
        return itemInUseCount;
    }

    public boolean isUsingItem() {
        return itemInUse != null;
    }

    public int getItemInUseDuration() {
        if (isUsingItem())
            return itemInUse.getMaxItemUseDuration() - itemInUseCount;
        else
            return 0;
    }

    public void stopUsingItem() {
        if (itemInUse != null)
            itemInUse.onPlayerStoppedUsing(worldObj, null, itemInUseCount);
        clearItemInUse();
    }

    public void clearItemInUse() {
        itemInUse = null;
        itemInUseCount = 0;
    }
    
    protected void updateEntityActionState() {
    	super.updateEntityActionState();
        int i = getSwingSpeedModifier();
        if (isSwinging) {
            swingProgressInt++;
            if (swingProgressInt >= i) {
                swingProgressInt = 0;
                isSwinging = false;
            }
        } else {
            swingProgressInt = 0;
        }
        swingProgress = (float)swingProgressInt / (float)i;
    }
    
    private int getSwingSpeedModifier() {
        if (isPotionActive(Potion.digSpeed)) {
            return 6 - (1 + getActivePotionEffect(Potion.digSpeed).getAmplifier()) * 1;
        }
        if (isPotionActive(Potion.digSlowdown)) {
            return 6 + (1 + getActivePotionEffect(Potion.digSlowdown).getAmplifier()) * 2;
        } else {
            return 6;
        }
    }
	
    public void writeEntityToNBT(NBTTagCompound saveData)
    {
        super.writeEntityToNBT(saveData);
        NBTTagList invData = new NBTTagList();
        inventory.writeToNBT(invData);
        saveData.setTag("inventory", invData);
    }

    public void readEntityFromNBT(NBTTagCompound saveData)
    {
        super.readEntityFromNBT(saveData);
        texture = "/mob/char.png";
        inventory.readFromNBT((NBTTagList) saveData.getTag("inventory"));
    }

	public void setWaypoint(int x, int y, int z) {
		waypoint = new EntityWaypoint(worldObj, x, y, z);
		getNavigator().func_46071_a(x, y, z, moveSpeed);
	}
	
	public boolean doneWalking() {
		return getNavigator().func_46072_b();
	}
	
}
